#include "pch.h"
#include "MainController.h"
#include <ppltasks.h>

using namespace TicTacToe;
using namespace concurrency;

MainController::MainController(TicTacToe::DirectXPage^ page, GameModel^ model)
{
	Model = model;
	View = page;

	this->TicTacToeAI = ref new TicTacToe::TicTacToeAI();

	//Hinweis: Die Lambda Expression wird im IntelliSense vom VS als Error angezeigt: Known Issue
	View->NewGameRequested += ref new NewGameRequestedHandler([this]() {HandleNewGameRequested(); });
	View->FieldSelected += ref new FieldSelectedHandler([this]() {HandleFieldSelected(); });
}
/*
MainController::~MainController(void)
{
}*/

void MainController::HandleNewGameRequested()
{
	Model->InitializeGame();

	View->UpdateView();
}

void MainController::HandleFieldSelected()
{
	if(!CheckGameHasWinner() && !CheckGameIsOver())
	{
		SwitchPlayer();

		if(Model->CurrentPlayer == COMPUTER_PLAYER)
		{
			Windows::Foundation::IAsyncAction^ action = create_async([this]() -> void {
				this->MakeAITurn();
			});
		}
	}
}

void MainController::MakeAITurn()
{
	Sleep(1000);

	Cell^ cell = TicTacToeAI->GetNextTurn(this->Model);

	Model->Cells->SetCurrentPlayerInCell(cell->Column, cell->Row, Model->CurrentPlayer);

	auto dispatcher = View->Dispatcher;
	dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,
								 ref new Windows::UI::Core::DispatchedHandler([this]() {
		SwitchPlayer();
		View->UpdateView();

		if(!CheckGameHasWinner())
		{
			CheckGameIsOver();
		}
	}));
}

bool MainController::CheckGameHasWinner()
{
	int winnerPlayer = Model->CheckForHorizontalWinner();
	if(winnerPlayer > 0)
	{
		Model->WinnerPlayer = winnerPlayer;
		Model->GameOver = true;
		return true;
	}

	winnerPlayer = Model->CheckForVerticalWinner();
	if(winnerPlayer > 0)
	{
		Model->WinnerPlayer = winnerPlayer;
		Model->GameOver = true;
		return true;
	}

	winnerPlayer = Model->CheckForDiagonalWinner();
	if(winnerPlayer > 0)
	{
		Model->WinnerPlayer = winnerPlayer;
		Model->GameOver = true;
		return true;
	}

	return false;
}

bool MainController::CheckGameIsOver()
{
	auto freeCells = Model->Cells->GetFreeCells();
	if(freeCells->Size == 0)
	{
		Model->GameOver = true;
		return true;
	}
	return false;
}

void MainController::SwitchPlayer(){
	switch (Model->CurrentPlayer)
	{
		case 1:
			Model->CurrentPlayer = 2;
			break;
		case 2:
			Model->CurrentPlayer = 1;
			break;
		default:
			break;
	}
} 

void MainController::Sleep(int milliseconds)
{
	//Kommt einem Thread Sleep gleich
	HANDLE m_event;
	m_event = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
	WaitForSingleObjectEx(m_event, milliseconds, false);
}